#include <stdio.h>
#include <ulog/ulog.h>
#include "iic_function.h"
#include "camera_config.h"
#include "drv_isp.h"
#include "soc.h"
#include "pin_name.h"
#include "irs2877c_drv.h"
#include "irs2877c_config.h"
#include "drv_gpio.h"

static i2c_dev_t i2c_irs2877c;

extern gpio_pin_handle_t gpio_pin_handle;

static int irs2877c_check_id(i2c_dev_t *i2c)
{
    int ret = 0;
    uint8_t data[2] = {0};

	ret = iic_read_r16_d16(i2c,  IRS2877C_ADDR_CHIPID, data);
	printf("irs2877c: chipID = 0x%02x, 0x%02x \n", data[0], data[1]);
	
   	//if (ret < 0 || (data[0] != 0x96) || (data[1] != 0xFD))
    //    return -1;

    return ret;
}

int irs2877c_hw_reset(int bitn)
{
//	printf("irs2877c: tof hardware reset. \n");
//	
//	//Config USI3_SCLK <=> GPIOB12  
//	
//    gpio_pin_handle = csi_gpio_pin_initialize(rst_n, 0);
//	
//    csi_gpio_pin_config_mode(gpio_pin_handle, GPIO_MODE_PULLDOWN);
//    csi_gpio_pin_config_direction(gpio_pin_handle, GPIO_DIRECTION_OUTPUT);
//    csi_gpio_pin_write(gpio_pin_handle, 0);
//	
//	aos_msleep(500);
//    csi_gpio_pin_write(gpio_pin_handle, 1);

	volatile uint32_t *base;
	base = (uint32_t *)(CSKY_AOGPIO_BASE + 0x04); //gpio dicrection
	*base |= (0x1 << bitn);
	base = (uint32_t *)(CSKY_AOGPIO_BASE + 0x00); //output
	*base |= (0x0 << bitn);
	aos_msleep(10);
	*base |= (0x1 << bitn);

	
    return 0;
}



int irs2877c_init(i2c_dev_t *i2c, uint32_t dev_addr)
{
   	memcpy(&i2c_irs2877c, i2c, sizeof(i2c_dev_t));
    i2c_irs2877c.config.dev_addr = dev_addr;
    //Check the id of camera
   	int ret = irs2877c_check_id(&i2c_irs2877c);
    if (ret < 0) {
        printf("irs2877c check id fail\n");
        return ret;
    }
	
    return ret;
}

int32_t irs2877c_mode_config(irs2877c_mode_e mode)
{
	int ret = 0;
	//printf("%s >>>>  %d, mode %d \n",__func__, __LINE__, mode);

	if (IRS2877C_STANDBY == mode) {
		ret = iic_write16bit_array(&i2c_irs2877c, (struct regval_list *)irs2877c_640x241x5_standby, ARRAY_SIZE(irs2877c_640x241x5_standby));
		if (ret < 0) {
			return -1;
		}
	} 
	else if(IRS2877C_STREAM == mode)
	{
		ret = iic_write16bit_array(&i2c_irs2877c, (struct regval_list *)irs2877c_640x241x5_stream, ARRAY_SIZE(irs2877c_640x241x5_stream));
		if (ret < 0) {
			return -1;
		}
	}
	else {}


	return 0;
}




int32_t irs2877c_config(imageFormat_t cfg)
{
	int32_t ret = 0;

	if( R_640x241x5 == cfg.res && RAW12 == cfg.format)
	{
		ret = iic_write16bit_array(&i2c_irs2877c, (struct regval_list *)irs2877c_640x241x5_raw12, ARRAY_SIZE(irs2877c_640x241x5_raw12));
		if (ret < 0) {
			return -1;
		}
		
		//irs2877c_mode_config(IRS2877C_STREAM);
		
#if 0
		
//		ret = iic_write16bit_array(&i2c_irs2877c, (struct regval_list *)irs2877c_640x241x5_stream, ARRAY_SIZE(irs2877c_640x241x5_stream));
//		if (ret < 0) {
//			return -1;
//		}

//		uint32_t num0 = 0;
//		uint32_t size0 = ARRAY_SIZE(irs2877c_640x241x5_stream);
//		uint8_t reg_dat0[2] = {0};
//		
//		while(num0 < size0)
//		{
//			iic_read16bit(&i2c_irs2877c, irs2877c_640x241x5_stream[num0].addr, reg_dat0);
//			printf("irs2877c addr = 0x%04x, d[0] = 0x%02x, d[1] = 0x%02x, \n", irs2877c_640x241x5_stream[num0].addr, reg_dat0[0], reg_dat0[1]);
//			num0++;
//		}

		uint32_t num = 0;
		uint32_t size = ARRAY_SIZE(irs2877c_640x241x5_raw12);
		uint8_t reg_dat[2] = {0};
		
		while(num < size)
		{
			iic_read16bit(&i2c_irs2877c, irs2877c_640x241x5_raw12[num].addr, reg_dat);
			printf("irs2877c addr = 0x%04x, d[0] = 0x%02x, d[1] = 0x%02x, \n", irs2877c_640x241x5_raw12[num].addr, reg_dat[0], reg_dat[1]);
			num++;
		}

		//while(1) {aos_msleep(500);}
#endif
		
		printf("irs2877c reg init done. \n");
	}

	return ret;
}



